package com.service.gmall.Item.api;

import com.service.gmall.Item.lock.RedisDistLock;
import com.service.gmall.common.result.Result;
import org.aspectj.weaver.ast.Var;
import org.redisson.api.RCountDownLatch;
import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author alpha
 * @className: LockTestController
 * @Description: 分布式锁测试
 */
@RestController
@RequestMapping("/lock")
public class LockTestController {

    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Autowired
    RedisDistLock redisDistLock;

    @Autowired
    RedissonClient client;

    //    ReentrantLock lock = new ReentrantLock();

    /**
     * shenlong
     * @return
     * @throws InterruptedException
     */
    @GetMapping("/shenlong")
    public String shenlong() throws InterruptedException {
        RCountDownLatch latch = client.getCountDownLatch("sl-lock");
        latch.trySetCount(3);
        latch.await();
        return "shenlong...";
    }

    /**
     * 闭锁
     * @return
     */
    @GetMapping("/collect")
    public String collect(){
        RCountDownLatch latch = client.getCountDownLatch("sl-lock");
        latch.countDown();
        return "collect finish...";
    }

    /**
     * 写锁
     * @return
     * @throws InterruptedException
     */
    @GetMapping("/rw/write")
    public String write() throws InterruptedException {
        RReadWriteLock lock = client.getReadWriteLock("rw-lock");
        //获取写锁
        RLock rLock = lock.writeLock();
        //加写锁
        rLock.lock();
        //业务逻辑
        Thread.sleep(10000);
        //解锁
        rLock.unlock();
        return "writing...";
    }

    /**
     * 读锁
     * @return
     */
    @GetMapping("/rw/read")
    public String read() {
        RReadWriteLock lock = client.getReadWriteLock("rw-lock");
        //获取读锁
        RLock rLock = lock.readLock();
        //加读锁
        rLock.lock();
        //读取操作
        String x = "xx";
        System.out.println("xx");
        //释放锁
        rLock.unlock();
        return "reading..." + x;
    }

    @GetMapping("/redisson/common")
    public String common() throws InterruptedException {
        RLock rLock = client.getLock("lock-hh");//这里写lock报错
        //加锁
        rLock.lock();//阻塞式
//        rLock.lock(10,TimeUnit.SECONDS);//阻塞式，规定时间释放锁
//        rLock.tryLock();//尝试抢锁，抢不到不等
//        rLock.tryLock(10,TimeUnit.SECONDS);//最多等10秒
//        rLock.tryLock(10,10,TimeUnit.SECONDS);//等10秒，等到加锁20秒
        System.out.println("加锁ing");
        //执行业务
        Thread.sleep(5000);
        System.out.println("业务执行结束...");
        //解锁
        rLock.unlock();
        return "success";
    }

    @GetMapping("/incr")
    public Integer incr() {
//        lock.lock();//本地锁
        String token = redisDistLock.lock();//分布式锁
        System.out.println("loading...");
        String a = stringRedisTemplate.opsForValue().get("a");
        int i = Integer.parseInt(a);
        i++;
        stringRedisTemplate.opsForValue().set("a", i + "");
//        lock.unlock();
        redisDistLock.unlock(token);
        return i;
    }
}
